#!/usr/bin/env python3
# _*_ coding:utf-8 _*_

import os
import git

StoreHouse = 'D:\\data\\'

backup_num = 5


# git_path = os.path.abspath('..')
# # print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
CODE_PATH= StoreHouse
BACKUP_NUM = backup_num

class CodeAutoDeploy(object):
    def __init__(self, git_url=None, pro_dir=None, branch_name='master', deploy_branch_name='deploy'):
        """
        :param git_url: git 项目仓库地址
        :param pro_dir: 项目本地clone  路径
        :param branch_name:  拉取的分支名
        :param deploy_branch_name:  用于部署，备份的
        store_dir 项目存在本地仓库 路径
        """
        self.git_url = git_url
        self.pro_dir = pro_dir
        self.branch_name = branch_name
        self.deploy_branch_name = deploy_branch_name
        self.store_dir = CODE_PATH
        self.backup_num = str(BACKUP_NUM)
        if not os.path.exists(self.store_dir):
            os.makedirs(self.store_dir)

    def git_clone(self):
        git_dir = os.path.join(self.pro_dir, '.git')
        try:

            if not os.path.exists(git_dir):
                git.Repo.clone_from(self.git_url, to_path=self.pro_dir, branch=self.branch_name)
                return [True, ]
            else:
                self.code_update()
                return [True, ]
        except Exception as e:
            return [False, e]

    def __repo(self):
        return git.Git(self.pro_dir)

    def get_branch(self):
        """
        :return: 返回本地deploy以及备份分支
        """
        repo = self.__repo()
        local_branch = repo.branch()
        branch_list = local_branch.replace(' ', '').replace('*', '').split('\n')
        if self.deploy_branch_name in branch_list:
            index_start = branch_list.index(self.deploy_branch_name)
            branch_list = branch_list[index_start:]
        index = branch_list.index(self.branch_name)
        return [branch_list, index]

    def mode_branch_name(self, old_name, new_name):
        repo = self.__repo()
        repo.branch('-m', old_name, new_name)

    def code_update(self):
        repo = self.__repo()
        repo.pull()

    def code_roll(self):
        repo = self.__repo()
        branch_list, index = self.get_branch()
        if len(branch_list) >= 2:

            dep_branch_list = branch_list[:index]
            dep_branch_list.reverse()
            for i in dep_branch_list:
                ver_list = i.split('-v')
                if len(ver_list) == 2:
                    if ver_list[1] == self.backup_num:
                        repo.branch('-d', i)
                        continue
                    version = int(ver_list[1]) + 1

                else:
                    version = 1
                curr_ver = i
                roll_ver = '%s-v%s' % (ver_list[0], version)
                self.mode_branch_name(curr_ver, roll_ver)
        repo.branch(self.deploy_branch_name)

    def code_rollback(self, roll_version=1):
        branch_list, a = self.get_branch()
        if len(branch_list) >= 2:
            dep_branch = '%s-v%s' % (self.deploy_branch_name, roll_version)
            if dep_branch in branch_list:
                index = branch_list.index(dep_branch)
                if roll_version <= int(self.backup_num):
                    self.mode_branch_name(dep_branch, '%s-v%s' % (self.deploy_branch_name, 'backup'))
                    list_part = branch_list[:index]
                    list_part.reverse()
                    for i in list_part:
                        ver_list = i.split('-v')
                        if len(ver_list) == 2:
                            version = int(ver_list[1]) + 1

                        else:
                            version = 1
                        self.mode_branch_name(i, '%s-v%s' % (self.deploy_branch_name, version))
                    self.mode_branch_name('%s-v%s' % (self.deploy_branch_name, 'backup'), self.deploy_branch_name)
                    return [True, ]
                else:
                    pass
            else:
                pass

        else:
            return [False, '没有可回滚版本']

    def code_diff(self, deploy, master):
        repo = self.__repo()
        info = repo.diff(deploy, master, '--name-status')
        return self.diff_info(info)

    def update_diff(self):
        return self.code_diff(self.deploy_branch_name, self.branch_name)

    def rollback_diff(self):
        return self.code_diff(self.branch_name, self.deploy_branch_name)

    def diff_info(self, info):
        info_list = info.strip().split('\n')
        diff_dict = {}
        for i in info_list:
            i_list = i.split()
            file_list = diff_dict.get(i_list[0], [])
            file_list.append(i_list[1].strip())
            diff_dict[i_list[0]] = file_list
        return diff_dict

    def check_branch(self, branch_name):
        repo = self.__repo()
        repo.checkout(branch_name)

    def look_now_branch(self):
        repo = self.__repo()
        info = repo.branch()
        return info

s1 = CodeAutoDeploy('https://gitee.com/Arno-lixi/git_test.git', 'D:/data/test')
print(s1.clone_status[1])
# s1.code_update()
